package hu.monitor.server.remoting;

import hu.monitor.remoting.InterceptorChain;
import hu.monitor.remoting.server.EjbInvokerInterceptor;
import hu.monitor.remoting.server.InterceptorChainRequestProcessor;
import hu.monitor.remoting.server.LoginInvokerInterceptor;
import hu.monitor.remoting.transport.SerializeMarshaller;
import hu.monitor.remoting.transport.ServerEndpointAdapter;
import hu.monitor.remoting.transport.socket.SocketServerEndpoint;
import hu.monitor.server.qualifier.ServerEndpoint;

import java.io.IOException;
import java.net.SocketAddress;
import java.util.Arrays;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Startup
@Singleton
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class RemotingBootstrap {
	private static Logger log = LoggerFactory.getLogger(RemotingBootstrap.class);

	private SocketServerEndpoint serverEndpoint;

	@Inject
	@ServerEndpoint
	private SocketAddress bindingAddress;

	@Inject
	private EjbInvokerInterceptor ejbInvoker;

	@Inject
	private LoginInvokerInterceptor login;

	@PostConstruct
	public void bootstrap() throws IOException {
		log.info("Starting remoting");

		final InterceptorChain chain = new InterceptorChain(Arrays.asList(this.login, this.ejbInvoker));
		final InterceptorChainRequestProcessor processor = new InterceptorChainRequestProcessor(chain);
		final ServerEndpointAdapter adapter = new ServerEndpointAdapter(new SerializeMarshaller(), processor);
		this.serverEndpoint = new SocketServerEndpoint(this.bindingAddress, adapter);
		this.serverEndpoint.startAcceptor();
	}

	@PreDestroy
	public void shutdown() throws IOException {
		log.info("stopping remoting");
		this.serverEndpoint.stopAcceptor();
	}
}
